package com.sfx.concurrent.demo.concurrent.AtomicTest.MyUnSafe;

import com.sfx.concurrent.demo.concurrent.AtomicTest.Account.Account;
import sun.misc.Unsafe;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sfx
 * Date: 2023-01-19
 * Time: 18:56
 */
public class MyUnSafe implements Account {

    private volatile int value;
    private static final long valueOffset;
    private static final Unsafe UNSAFE;
    static {
        UNSAFE = UnSafeAccessor.getUnsafe();
        try {
            valueOffset = UNSAFE.objectFieldOffset(MyUnSafe.class.getDeclaredField("value"));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    public int getValue() {
        return value;
    }

    public MyUnSafe(int value) {
        this.value = value;
    }

    public void decrement(int account) {
        while(true) {
            int prev = this.value;
            int next = this.value - account;
            if(UNSAFE.compareAndSwapInt(this,valueOffset,prev,next)) {
               break;
            }
        }
    }

    @Override
    public Integer getBalance() {
        return value;
    }

    @Override
    public void withDraw(int account) {
        decrement(account);
    }

    public static void main(String[] args) {
        MyUnSafe myUnSafe = new MyUnSafe(10000);
        Account.demo(myUnSafe);
    }
}